/*
 * Copyright © OpenAtom Foundation.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package io.iec.edp.caf.databaseobject.api.context;


import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import io.iec.edp.caf.databaseobject.api.configuration.DatabaseObjectConfiguration;
import io.iec.edp.caf.databaseobject.api.entity.DatabaseObjectColumn;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据库对象保留字段信息
 *
 * @author zhaoleitr
 */
public final class ReservedColumns {
    private static ArrayList<DatabaseObjectColumn> timeStampColumns;

    /**
     * 时间戳字段列表
     */
    public static ArrayList<DatabaseObjectColumn> getTimeStampColumns() {
        if (timeStampColumns == null || timeStampColumns.size() <= 0) {
            try {
                timeStampColumns = getTimeStampColumnsFromConf();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return timeStampColumns;
    }

    private static DatabaseObjectColumn tenantIDColumn;

    /**
     * 租户标识字段
     */
    public static DatabaseObjectColumn getTenantIdColumn() {
        if (tenantIDColumn == null) {
            try {
                tenantIDColumn = getTenantIdColumnfromConf();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return tenantIDColumn;
    }

    private static String reservedColumns = "{\"TimeStampColumns\": [{\"DataType\": 9,\"DataTypeStr\": \"NVarchar\",\"Length\": 256,\"Precision\": 0,\"Scale\": 0,\"DefaultValue\": \"\",\"IfPrimaryKey\": false,\"IsNullable\": true,\"IsUnique\": false,\"ID\": \"dbc24616-3f96-4bb4-9870-b3044a7c69ff\",\"Code\": \"CreatedBy\",\"Name\": \"CreatedBy\",\"Description\": null,\"Type\": 3,\"TypeStr\": \"Column\",\"Version\": null},{\"DataType\": 6,\"DataTypeStr\": \"TimeStamp\",\"Length\": 0,\"Precision\": 0,\"Scale\": 0,\"DefaultValue\": \"\",\"IfPrimaryKey\": false,\"IsNullable\": true,\"IsUnique\": false,\"ID\": \"gt524616-3f96-4bb4-9870-b3044a7c69ff\",\"Code\": \"CreatedOn\",\"Name\": \"CreatedOn\",\"ShowName\": null,\"Description\": null,\"Type\": 3,\"TypeStr\": \"Column\",\"Version\": null},{\"DataType\": 9,\"DataTypeStr\": \"NVarchar\",\"Length\": 256,\"Precision\": 0,\"Scale\": 0,\"DefaultValue\": \"\",\"IfPrimaryKey\": false,\"IsNullable\": true,\"IsUnique\": false,\"ID\": \"v4s24616-3f96-4bb4-9870-b3044a7c69ff\",\"Code\": \"LastChangedBy\",\"Name\": \"LastChangedBy\",\"Description\": null,\"Type\": 3,\"TypeStr\": \"Column\",\"Version\": null},{\"DataType\": 6,\"DataTypeStr\": \"TimeStamp\",\"Length\": 0,\"Precision\": 0,\"Scale\": 0,\"DefaultValue\": \"\",\"IfPrimaryKey\": false,\"IsNullable\": true,\"IsUnique\": false,\"ID\": \"3f524616-3f96-4bb4-9870-b3044a7c69ff\",\"Code\": \"LastChangedOn\",\"Name\": \"LastChangedOn\",\"Description\": null,\"Type\": 3,\"TypeStr\": \"Column\",\"Version\": null}],\"TanantIDColumn\": {\"DataType\": 1,\"DataTypeStr\": \"Varchar\",\"Length\": 256,\"Precision\": 0,\"Scale\": 0,\"DefaultValue\": \"\",\"IfPrimaryKey\": false,\"IsNullable\": true,\"IsUnique\": false,\"ID\": \"efsa4616-3f96-4bb4-9870-b3044a7c69ff\",\"Code\": \"TenantID\", \"Name\": \"TenantID\", \"Description\": null,\"Type\": 3, \"TypeStr\": \"Column\",\"Version\": null}}";

    private static ArrayList<DatabaseObjectColumn> getTimeStampColumnsFromConf() throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //N转J忽略大小写
        mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
        JsonNode rootNode = mapper.readTree(reservedColumns);

        String content = rootNode.findValue("TimeStampColumns").toString();
        return mapper.readValue(content, new TypeReference<ArrayList<DatabaseObjectColumn>>() {
        });

    }

    private static DatabaseObjectColumn getTenantIdColumnfromConf() throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //N转J忽略大小写
        mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
        JsonNode rootNode = mapper.readTree(reservedColumns);
        String content = rootNode.findValue("TanantIDColumn").toString();
        return mapper.readValue(content, DatabaseObjectColumn.class);
    }

    private static JavaType getCollectionType(ObjectMapper mapper, Class<?> collectionClass, Class<?>... elementClasses) {
        return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }
}
